/*****************************************************************\
           __
          / /
		 / /                     __  __
		/ /______    _______    / / / / ________   __       __
	   / ______  \  /_____  \  / / / / / _____  | / /      / /
	  / /      | / _______| / / / / / / /____/ / / /      / /
	 / /      / / / _____  / / / / / / _______/ / /      / /
	/ /      / / / /____/ / / / / / / |______  / |______/ /
   /_/      /_/ |________/ / / / /  \_______/  \_______  /
                          /_/ /_/                     / /
			                                         / /
		       High Level Game Framework            /_/

  ---------------------------------------------------------------

  Copyright (c) 2007-2011 - Rodrigo Braz Monteiro.
  This file is subject to the terms of halley_license.txt.

\*****************************************************************/

#pragma once

#if defined(_WIN32) && !defined(WITH_GDK)

#define _WIN32_DCOM
#include "os_winbase.h"
#include <wbemidl.h>

namespace Halley {
	class OSWin32 final : public OSWinBase {
	public:
		OSWin32();
		~OSWin32() override;

		void createLogConsole(String name, std::optional<size_t> monitor, Vector2f align) override;
		void initializeConsole() override;

		ComputerData getComputerData() override;
		String getComputerName() override;
		String getUserDataDir() override;
		String getCurrentWorkingDir() override;
		String getEnvironmentVariable(const String& name) override;
		Path parseProgramPath(const String&) override;
		void setConsoleColor(int foreground, int background) override;
		bool atomicWriteFile(const Path& path, gsl::span<const std::byte> data, std::optional<Path> backupOldVersionPath) override;

		void displayError(std::string_view cs) override;
		void onWindowCreated(void* window) override;

		int runCommand(String command, String cwd, ILoggerSink* sink) override;
		Future<int> runCommandAsync(const String& string, const String& cwd, ILoggerSink* sink) override;
		bool runCommandDetached(const String& string, const String& cwd) override;
		void runCommand(StringUTF16 command, StringUTF16 cwd, Promise<int> promise, ILoggerSink* sink);

		std::shared_ptr<IClipboard> getClipboard() override;

		void openURL(const String& url) override;
		void openFile(const Path& path) override;
		void showFile(const Path& path) override;
		Future<std::optional<Path>>	openFileChooser(FileChooserParameters parameters) override;

		uint64_t getMemoryUsage() override;

		Vector<String> runQuery(std::string_view query, gsl::span<const String> parameters, std::string_view queryNamespace) const override;
		ConfigNode getRegistryString(std::string_view key) const override;

		void setEnvVariable(std::string_view name, std::string_view value) override;

	private:
		String runWMIQuery(std::string_view query, const String& parameter, std::string_view queryNamespace = "root/cimv2") const;
		Vector<String> runWMIQuery(std::string_view query, gsl::span<const String> parameters, std::string_view queryNamespace = "root/cimv2") const;
		IWbemServices* getIWbemService(std::string_view queryNamespace) const;
		void loadWindowIcon(HWND hwnd);

	private:
		IWbemLocator *pLoc;
		mutable HashMap<String, IWbemServices*> pSvcs;
		HICON icon;
	};
}

#endif
